import random

from django.utils import timezone
from langchain.agents import initialize_agent, Tool
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from django.shortcuts import get_object_or_404
from django.core.mail import send_mail
from django.conf import settings
from .models import (
    WorkFlowModel, WorkFlowPermissionModel, TaskModel,
    ApprovalRecordModel, UserRbacModel, WorkFlowApprovalModel
)
import json
from langchain_community.llms import Tongyi


# Tool functions
def submit_request(request_data):
    try:
        if isinstance(request_data, str):
            request_data = json.loads(request_data)

        # 校验 params 是否是 JSON 格式
        params = request_data.get('params')
        if isinstance(params, str):
            params = json.loads(params)  # 尝试将字符串解析为 JSON 对象

        workflow = WorkFlowModel.objects.get(id=request_data['workflow_id'])
        task = TaskModel.objects.create(
            name=f"{workflow.name} - 任务",
            params=json.dumps(params),  # 确保存储为 JSON 格式
            workflow=workflow,
            user_id=request_data['userid'],
            task_status=0  # 初始状态
        )
        return int(task.id)
    except json.JSONDecodeError as e:
        print(f"参数 JSON 格式错误: {e}")
        return None
    except Exception as e:
        print(f"提交请求失败: {e}")
        return None






def assign_approver(request_id):
    """分配下一个审批人"""
    try:
        if isinstance(request_id, dict):
            request_id = request_id.get('request_id')

        task = TaskModel.objects.get(id=request_id)
        current_level = ApprovalRecordModel.objects.filter(task=task).count() + 1

        next_approval = WorkFlowApprovalModel.objects.filter(
            workflow=task.workflow,
            level=current_level
        ).first()

        if next_approval:
            # 从符合条件的用户中随机选择
            potential_approvers = UserRbacModel.objects.filter(
                position=next_approval.position
            )

            if potential_approvers.exists():
                next_approver = random.choice(potential_approvers)  # 随机选择
                return int(next_approver.id)
        return None
    except Exception as e:
        print(f"分配审批人失败: {e}")
        return None




def record_decision(request_id, decision):
    """记录审批决定"""
    try:
        if isinstance(request_id, dict):
            request_id = request_id.get('request_id')

        task = TaskModel.objects.get(id=request_id)
        current_record = ApprovalRecordModel.objects.get(
            task=task,
            audit_status=0  # 审批中
        )
        # 更新当前审批记录
        current_record.audit_status = 0 if decision.get('status') == 'approved' else 1
        current_record.audit_time = timezone.now()
        current_record.save()

        # 检查是否还有下一审批步骤
        current_level = current_record.audit_level
        next_approval = WorkFlowApprovalModel.objects.filter(
            workflow=task.workflow,
            level=current_level + 1
        ).exists()

        if not next_approval:  # 如果没有更多审批步骤
            # 检查是否所有审批人都通过
            all_approved = ApprovalRecordModel.objects.filter(
                task=task,
                audit_status=1  # 拒绝
            ).exists()

            if not all_approved:  # 如果所有都通过
                task.task_status = 2  # 更新为完成状态
                task.save()
        else:
            # 分配下一个审批人
            next_approver_id = assign_approver(request_id)
            if next_approver_id:
                record=ApprovalRecordModel.objects.create(
                    task=task,
                    audit_level=current_level + 1,
                    audit_user=next_approver_id,
                    audit_status=0  # 待审批
                )
                print(f"新审批记录创建成功: {record}")  # 打印新记录
                task.next_audit = next_approver_id
                task.save()
        return True
    except Exception as e:
        print(f"记录决定失败: {e}")
        return False



def update_status(request_id, status_value):
    """更新任务状态"""
    try:
        # 确保参数类型正确
        if isinstance(request_id, dict):
            request_id = request_id.get('request_id')
        if isinstance(status_value, dict):
            status_value = status_value.get('status')

        task = TaskModel.objects.get(id=request_id)
        task.task_status = int(status_value)
        task.save()
        return True
    except Exception as e:
        print(f"更新状态失败: {e}")
        return False


def send_approval_email(user_email, task_id, approval_url):
    """发送审批邮件"""
    subject = '新的任务审批请求'
    message = f'''
    您有一个新的任务等待审批。
    请点击以下链接进行审批:
    {approval_url}?task_id={task_id}
    '''
    send_mail(
        subject,
        message,
        settings.DEFAULT_FROM_EMAIL,
        [user_email],
        fail_silently=False,
    )


# Initialize tools and agent
# 修改工具描述，使其更明确
tools = [
    Tool(
        name="SubmitRequest",
        func=submit_request,
        description="Submit a workflow request and return the task ID. Input should be a dictionary with workflow_id, userid, and params."
    ),
    Tool(
        name="AssignApprover",
        func=assign_approver,
        description="Get the next approver's ID for a task. Input should be a task ID number."
    ),
    Tool(
        name="RecordDecision",
        func=record_decision,
        description="Record an approval decision. Input should be a task ID and a decision dictionary."
    ),
    Tool(
        name="UpdateStatus",
        func=update_status,
        description="Update task status. Input should be a task ID and a status number."
    )
]

llm = Tongyi()
agent = initialize_agent(
    tools,
    llm,
    agent="zero-shot-react-description",
    verbose=True,
    handle_parsing_errors=True  # 启用解析错误处理
)




class UserTaskView(APIView):
    def get(self, request):
        user_id = request.GET.get('userid')
        print(user_id,1111111111111111)
        user = get_object_or_404(UserRbacModel, id=user_id)

        # Get workflows based on user role
        allowed_workflows = WorkFlowPermissionModel.objects.filter(
            role=user.roles
        ).values_list('workflow', flat=True)
        print(allowed_workflows,2222222222222222222222222222)
        workflows = WorkFlowModel.objects.filter(id__in=allowed_workflows, status=1)
        print(workflows,33333333333333333333333333333)
        workflows_data = []
        for wf in workflows:
            # Get approval flow for each workflow
            approvers = []
            workflow_approvals = WorkFlowApprovalModel.objects.filter(
                workflow=wf
            ).order_by('level')

            for approval in workflow_approvals:
                approvers.append({
                    "level": approval.level,
                    "position": approval.position.name
                })
            print(approvers,222222222222222222222)
            workflows_data.append({
                "id": wf.id,
                "name": wf.name,
                "params": json.loads(wf.params),
                "approvers": approvers
            })

        return Response({"workflows": workflows_data}, status=status.HTTP_200_OK)


class TaskCreateView(APIView):
    def post(self, request):
        user_id = request.data.get('userid')
        workflow_id = request.data.get('wid')
        params = request.data.get('params')

        if not all([user_id, workflow_id, params]):
            return Response({"error": "缺少必要字段"}, status=status.HTTP_400_BAD_REQUEST)

        try:
            # 调用 Agent 执行任务创建
            task_id = agent.run(
                f"""
                Submit a workflow request with workflow_id={workflow_id}, userid={user_id}, 
                and params={json.dumps(params)}.  # 确保使用 json.dumps 格式化参数
                You must return only the numeric task ID. Do not return any explanation, text, 
                or additional information. Output must be a valid integer.
                """
            )

            print(f"Agent 返回的 task_id: {task_id}")  # 添加日志以查看返回值

            # 验证 task_id 是否有效
            if not task_id or not str(task_id).isdigit():
                return Response({"error": "创建任务失败，task_id 无效"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

            # 转换 task_id 为整数
            task_id = int(task_id)

            # 调用 Agent 获取下一个审批人
            next_approver_id = agent.run(
                f"Assign the next approver for task_id={task_id}. "
                "You must return only the numeric approver ID. Do not return any explanation, text, or additional information. "
                "Output must be a valid integer."
            )

            if next_approver_id:
                # 更新任务状态为“进行中”
                task = TaskModel.objects.get(id=task_id)
                task.task_status = 1  # 状态：进行中
                task.next_audit = next_approver_id
                task.save()

                # 创建审批记录
                ApprovalRecordModel.objects.create(
                    task=task,
                    audit_level=1,
                    audit_user=next_approver_id,
                    audit_status=0  # 待审批
                )

                # 发送审批邮件
                approver = UserRbacModel.objects.get(id=next_approver_id)
                if approver.email:
                    approval_url = f"{settings.FRONTEND_URL}/approve"
                    send_approval_email(approver.email, task_id, approval_url)

                return Response({
                    "message": "任务创建成功",
                    "task_id": task_id
                }, status=status.HTTP_201_CREATED)

            return Response({"error": "未找到审批人"}, status=status.HTTP_400_BAD_REQUEST)

        except Exception as e:
            return Response(
                {"error": f"创建任务失败: {str(e)}"},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )




class AuditWorkflowView(APIView):
    def post(self, request):
        task_id = request.data.get('task_id')
        decision = request.data.get('decision')

        if not all([task_id, decision]):
            return Response({"error": "Missing required fields"}, status=status.HTTP_400_BAD_REQUEST)

        try:
            # Record the decision
            if not agent.run("RecordDecision", {"request_id": task_id, "decision": decision}):
                return Response({"error": "Failed to record decision"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

            # Update task status to "审批中" (status=1)
            agent.run("UpdateStatus", {"request_id": task_id, "status": 1})

            # Get next approver
            next_approver_id = agent.run("AssignApprover", {"request_id": task_id})

            if next_approver_id:
                # Update task with next approver
                task = TaskModel.objects.get(id=task_id)
                task.next_audit = next_approver_id
                task.save()

                # Create new approval record
                current_level = ApprovalRecordModel.objects.filter(task_id=task_id).count() + 1
                ApprovalRecordModel.objects.create(
                    task_id=task_id,
                    audit_level=current_level,
                    audit_user=next_approver_id,
                    audit_status=0  # Pending
                )

                # Send email to next approver
                approver = UserRbacModel.objects.get(id=next_approver_id)
                if approver.email:
                    approval_url = f"{settings.FRONTEND_URL}/approve"
                    send_approval_email(approver.email, task_id, approval_url)

                return Response({
                    "message": "Decision recorded, next approver assigned",
                    "next_approver": next_approver_id
                }, status=status.HTTP_200_OK)
            else:
                # No more approvers, check if all approved
                task = TaskModel.objects.get(id=task_id)
                all_records_approved = ApprovalRecordModel.objects.filter(
                    task=task,
                    audit_status=0  # Approved
                ).count() == ApprovalRecordModel.objects.filter(task=task).count()

                if all_records_approved:
                    # Update task status to "已完成" (status=2)
                    agent.run("UpdateStatus", {"request_id": task_id, "status": 2})
                    return Response({
                        "message": "Workflow completed successfully"
                    }, status=status.HTTP_200_OK)
                else:
                    return Response({
                        "message": "Decision recorded, no more approvers"
                    }, status=status.HTTP_200_OK)

        except Exception as e:
            return Response(
                {"error": f"Failed to process approval: {str(e)}"},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )


# 获取任务详情
class TaskDetailView(APIView):
    def get(self, request, task_id):
        try:
            task = TaskModel.objects.get(id=task_id)
            # 获取当前任务的实际审批记录
            approval_records = ApprovalRecordModel.objects.filter(task=task).order_by('audit_time')

            # 获取该工作流的完整审批流程定义
            workflow_approvals = WorkFlowApprovalModel.objects.filter(
                workflow=task.workflow
            ).order_by('level')

            # 构建完整的审批流程信息
            approval_info = []
            for workflow_approval in workflow_approvals:
                # 查找该级别的实际审批记录
                record = approval_records.filter(audit_level=workflow_approval.level).first()

                approval_info.append({
                    "level": workflow_approval.level,
                    "position": workflow_approval.position.name,
                    "id": record.id if record else None,
                    "audit_status": record.audit_status if record else None,
                    "audit_user": UserRbacModel.objects.get(id=record.audit_user).name if record else None,
                    "audit_time": record.audit_time if record else None,
                })

            data = {
                "id": task.id,
                "name": task.name,
                "params": json.loads(task.params),
                "next_audit": task.next_audit,
                "approvalRecords": approval_info,
            }

            return Response(data, status=status.HTTP_200_OK)
        except TaskModel.DoesNotExist:
            return Response({"error": "Task not found"}, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            return Response({"error": f"Failed to fetch task: {str(e)}"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
